/**
 * http请求库，依赖配置`window.PROJECT_CONFIG.web.http`
 * @requires window.PROJECT_CONFIG.web.http
 * @requires axios
 */

import useAppName from '@framework/useAppName'
import useLog from '@framework/useLog'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import axios from 'axios'
import useConfig from '../useConfig/index'
import { clearAdd, clearSub, isFeatch } from './http_clearFetch'

/**
 * 接口去重处理
 */
export interface IsReset {
  isReset?: boolean
}

/**
 * http请求库
 */
export class HttpLib {
  httpConfig = useConfig().web?.http || {
    /**
     * 超时时间，单位：毫秒
     */
    timeout: 10000,
    /**
     * 接口的基础路径
     */
    baseURL: 'https://localhost:3000',
  }

  /**
   * 当前正在发起请求的个数
   */
  private _requestCount = 0
  set requestCount(v: number) {
    useLog().log('set requestCount ', v)
    this._requestCount = v
    this.countListeners.forEach((cb) => {
      cb(v)
    })
  }

  get requestCount() {
    return this._requestCount
  }

  axios: AxiosInstance

  /**
   * 报错的回调
   * @param {*} error
   */
  hookError(error: any) {
    console.log(error)
  }

  /**
   * 请求前的钩子
   * @param {object} config 请求的配置
   * @returns 修改后的配置
   */
  hookRequest(config: AxiosRequestConfig & IsReset) {
    return config
  }

  /**
   * 数据返回的钩子
   * @param {*} response
   * @returns
   */
  hookResponse(response: AxiosResponse) {
    return response
  }

  /**
   * 请求数的监听器
   */
  countListeners: ((count: number) => void)[] = []
  /**
   * 监听请求数量的变化
   * @param cb
   */
  onRequestCountChange(cb: (count: number) => void) {
    this.countListeners.push(cb)
  }

  /**
   * 请求库的构造函数
   * @param {{hookRequest?: Function, hookResponse?: Function, hookError?: Function}} option 构造参数
   */
  constructor(option: {
    hookError?: (error: any) => void
    hookRequest?: (config: AxiosRequestConfig<any> & IsReset) => AxiosRequestConfig<any> & IsReset
    hookResponse?: (response: AxiosResponse<any, any>) => AxiosResponse<any, any>
  }) {
    const config = useConfig<CoreConfig>()
    // 参数初始化
    if (option.hookError)
      this.hookError = option.hookError
    if (option.hookRequest)
      this.hookRequest = option.hookRequest
    if (option.hookResponse)
      this.hookResponse = option.hookResponse

    // 初始化
    this.axios = axios.create({
      timeout: config.web.http.timeout,
      // 默认为appname前缀
      baseURL: config.web.http.baseURL || `/${useAppName()}/proxy/`,
    })

    // 附加个属性给axios，监听正在请求的接口数量
    this.requestCount = 0

    this.axios.interceptors.request.use((config: any) => {
      const { isReset, url } = config
      if (isReset) {
        // 第一步：先终止前面相同的接口
        console.log(isFeatch(url as string))
        if (isFeatch(url as string))
          clearSub(url)

        // 第二步：添加实例
        const controller = new AbortController()
        config.signal = controller.signal
        clearAdd(url as string, controller)
      }
      this.requestCount++
      return this.hookRequest(config)
    })

    this.axios.interceptors.response.use((response) => {
      this.requestCount--
      if (this.requestCount < 0)
        this.requestCount = 0
      return this.hookResponse(response)
    }, (error) => {
      console.log(error)

      this.requestCount--
      if (this.requestCount < 0)
        this.requestCount = 0
      return this.hookError(error)
    })
  }
}
